package com.hsh.maoduo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hsh.maoduo.common.Result;
import com.hsh.maoduo.comparator.GoodsComparator;
import com.hsh.maoduo.constant.ExportPathConstants;
import com.hsh.maoduo.constant.common.DateConstants;
import com.hsh.maoduo.constant.common.GlobalPathConstants;
import com.hsh.maoduo.mapper.GoodsMapper;
import com.hsh.maoduo.pojo.dto.GoodsDTO;
import com.hsh.maoduo.pojo.dto.OutboundDTO;
import com.hsh.maoduo.pojo.entity.Goods;
import com.hsh.maoduo.pojo.export.GoodsExport;
import com.hsh.maoduo.pojo.vo.GoodsVO;
import com.hsh.maoduo.pojo.vo.InboundVO;
import com.hsh.maoduo.pojo.vo.OutboundVO;
import com.hsh.maoduo.service.GoodsService;
import com.hsh.maoduo.service.InboundService;
import com.hsh.maoduo.service.OutboundService;
import com.hsh.maoduo.util.ClassUtil;
import com.hsh.maoduo.util.DataUtil;
import com.hsh.maoduo.util.MyBeanUtils;
import com.hsh.maoduo.util.POIExcelUtil;
import org.apache.logging.log4j.util.Strings;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author USER
 * @description 针对表【goods】的数据库操作Service实现
 * @createDate 2023-12-23 16:35:07
 */
@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements GoodsService {

    @Resource
    private GoodsMapper goodsMapper;
    @Resource
    @Lazy
    private OutboundService outboundService;
    @Resource
    @Lazy
    private InboundService inboundService;

    @Override
    public List<GoodsDTO> getList(GoodsVO goodsVO) {
        //商品列表
        QueryWrapper<Goods> wrapper = new QueryWrapper<Goods>()
                .eq("is_delete", 0)
                .orderBy(true, true, "goods_name");
        if (Strings.isNotBlank(goodsVO.getGoodsName())) {
            wrapper.and(w -> w.like("goods_name", DataUtil.removeSpaceAndSymbols(goodsVO.getGoodsName()))
                    .or()
                    .like("simple_goods_name", DataUtil.removeSpaceAndSymbols(goodsVO.getGoodsName())));
        }

        List goodsList = goodsMapper.selectList(wrapper);
        List<GoodsDTO> goodsDTOList = MyBeanUtils.copyList(goodsList, GoodsDTO.class);
        //7天内各商品出库数量 （七天前0:00 ~ 今天0:00）
        OutboundVO outboundVO = new OutboundVO()
                .setStartDateTime(LocalDate.now().minusDays(30).toString())
//                .setStartDateTime(LocalDate.now().minusDays(7).toString())
                .setEndDateTime(LocalDate.now().plusDays(1).toString());
        List<OutboundDTO> outboundDTOList = MyBeanUtils.copyList(outboundService.getSumGroupByGoodId(outboundVO), OutboundDTO.class);
        //初始化 DTO类
        goodsDTOList.stream().forEach(v -> v.init(outboundDTOList));
        //排序
        goodsDTOList = goodsDTOList.stream()
                .sorted(GoodsComparator::compare)
                .collect(Collectors.toList());
        return goodsDTOList;
    }

    @Override
    public Result export(GoodsVO goodsVO) {
        List<GoodsDTO> goodsDTOList = getList(goodsVO);
        List<GoodsExport> goodsExportList = MyBeanUtils.copyList(goodsDTOList, GoodsExport.class);
        int rowNum = POIExcelUtil.write(ExportPathConstants.GOODS_PATH_PRE
                        + ExportPathConstants.GOODS_NAME_PRE
                        + DateConstants.PURE_DATETIME_FORMAT.format(new Date())
                        + GlobalPathConstants.XLSX_SUF
                , goodsExportList, GoodsExport.class);
        return Result.create(rowNum);
    }

    @Override
    public Result addOne(GoodsVO goodsVO) {
        int insertNum = 0;
        QueryWrapper<Goods> wrapper = new QueryWrapper<Goods>().eq("goods_name", goodsVO.getGoodsName());
        Goods oldGoods = goodsMapper.selectOne(wrapper);
        if (oldGoods == null) {
            Goods goods = MyBeanUtils.copy(goodsVO, Goods.class);
            insertNum = goodsMapper.insert(goods);
        }
        return Result.create(insertNum);
    }

    @Override
    public Result update(GoodsVO goodsVO) {
        Goods oldGoods = goodsMapper.selectById(goodsVO.getId());
        if (oldGoods == null) {
            return Result.fail("修改的数据不存在");
        }
        Date now = new Date();
        if (oldGoods.getNum() > goodsVO.getNum()) {
            outboundService.addOne(new OutboundVO()
                    .setNo(DateConstants.PURE_DATETIME_MS_FORMAT.format(now))
                    .setGoodsId(goodsVO.getId())
                    .setNum(oldGoods.getNum() - goodsVO.getNum())
                    .setShopId(goodsVO.getShopId())
                    .setNote(goodsVO.getNote())
                    .setCreateTime(now));
        } else if (oldGoods.getNum() < goodsVO.getNum()) {
            inboundService.addOne(new InboundVO()
                    .setNo(DateConstants.PURE_DATETIME_MS_FORMAT.format(now))
                    .setGoodsId(goodsVO.getId())
                    .setNum(goodsVO.getNum() - oldGoods.getNum())
                    .setSupplierId(goodsVO.getShopId())
                    .setNote(goodsVO.getNote())
                    .setCreateTime(now));
        }
        int updateNum = goodsMapper.updateById(MyBeanUtils.copy(goodsVO, Goods.class));
        return Result.create(updateNum);
    }

    @Override
    public Result delete(int id) {
        int deleteNum = goodsMapper.updateById(new Goods().setId(id).setIsDelete(1));
        return Result.create(deleteNum);
    }

    @Override
    @Transactional
    public int updateGoodsNum(Integer id, int updateNum) {
        Goods goods = goodsMapper.selectById(id);
        if (goods == null) {
            return 0;
        }
        UpdateWrapper<Goods> wrapper = new UpdateWrapper<>();
        wrapper.setSql("num = num + " + updateNum);
        wrapper.eq("id", id);
        return goodsMapper.update(goods, wrapper);
    }

    /**
     * 删除没有库存的商品
     * @param tList
     * @return
     * @param <T>
     */
    public  <T> List<T> removeOutOfStockOrders(List<T> tList) {
        List<T> inStcokList = new ArrayList<>();
        //有库存的商品集合
        QueryWrapper wrapper = new QueryWrapper<>().gt("num",0);
        List<Goods> inStockGoods =  goodsMapper.selectList(wrapper);
        for (T t : tList) {
            String goodsInfo = (String) ClassUtil.getFiled(t, "goodsInfo");
            Integer num = (Integer) ClassUtil.getFiled(t, "num");
            if (Strings.isBlank(goodsInfo)) {
                continue;
            }
            for (Goods inStockGood : inStockGoods) {
                boolean haveGoods = DataUtil.include(goodsInfo, inStockGood.getGoodsName())
                        || DataUtil.include(goodsInfo, inStockGood.getSimpleGoodsName());
                boolean haveStock = (num <= inStockGood.getNum());
                if (haveGoods && haveStock) {
                    //库存足够时，加入到结果集中
                    inStcokList.add(t);
                    //修改商品剩余库存
                    inStockGood.setNum(inStockGood.getNum() - num);
                    break;
                }
            }
        }
        Collections.reverse(inStcokList);
        return inStcokList;
    }
}




